package club.ruanx.movie.security;

import club.ruanx.security.filter.JwtTokenAuthenticationFilter;
import club.ruanx.security.provider.AuthorizeConfigProviderManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * @author 阮胜
 * @date 2018/9/15 10:41
 */

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    private final AuthorizeConfigProviderManager authorizeConfigProviderManager;
    private final JwtTokenAuthenticationFilter jwtTokenAuthenticationFilter;
    private final AccessDeniedHandler accessDeniedHandler;
    private final AuthenticationEntryPoint authenticationEntryPoint;

    public SecurityConfig(AuthorizeConfigProviderManager authorizeConfigProviderManager, JwtTokenAuthenticationFilter jwtTokenAuthenticationFilter, AccessDeniedHandler accessDeniedHandler, AuthenticationEntryPoint authenticationEntryPoint) {
        this.authorizeConfigProviderManager = authorizeConfigProviderManager;
        this.jwtTokenAuthenticationFilter = jwtTokenAuthenticationFilter;
        this.accessDeniedHandler = accessDeniedHandler;
        this.authenticationEntryPoint = authenticationEntryPoint;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        //手动实现的权限验证管理器
        authorizeConfigProviderManager.configure(http.authorizeRequests());
        http
                .csrf().disable()
                .headers().frameOptions().disable().and()
                .logout().disable()
                .formLogin().disable()
                .anonymous()
                .and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                //未登录,没有权限访问某资源时触发
                .exceptionHandling().authenticationEntryPoint(authenticationEntryPoint)
                //已登录,但没有权限访问某资源时触发
                .accessDeniedHandler(accessDeniedHandler)
                .and()
                .addFilterAfter(jwtTokenAuthenticationFilter,
                        UsernamePasswordAuthenticationFilter.class);
        //使用注解进行权限控制,所以不需要下面两行配置.
//                .authorizeRequests()
//                .anyRequest().authenticated();
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}
